home *** CD-ROM | disk | FTP | other *** search
- ;==========================================================================;
- ; 8530 Services ;
- ; ;
- ; Copyright 1986, 1987 by H. Roy Engehausen. All rights reserved. ;
- ; This software may be freely distributed and used, but it may not ;
- ; under any circumstances be sold by anyone other than the author. ;
- ; It may be distributed by a commercial company as long as it is ;
- ; for no cost. ;
- ; ;
- ; Permission is explicity granted to use this code as a model for ;
- ; other programs requiring interrupt driven serial I/O as long as they ;
- ; carry this copyright notice and the imbedded constants ;
- ; ;
- ; These run disabled for the most part because of the nature of ;
- ; reading and writing the 8530. ;
- ; ;
- ; AL = parameter ;
- ; AH = opcode ;
- ; BL = COM number - 1 (0 = COM1, 1=COM2, ...) ;
- ; ;
- ; Opcode 0 -- Initialize ;
- ; Parms ;
- ; xxx..... = Data rate. Use same settings as IBM ROM BIOS. ;
- ; 300 bps = 2, 1200 bps= 4. ;
- ; ;
- ; ...x.... = Full duplex if 1. Half duplex if 0. ;
- ; ;
- ; ....x... = Error packet handler. 0 = throw away all error ;
- ; packets. ;
- ; ;
- ; .....xxx = Don't care. Use 0 for now! ;
- ; ;
- ; Special case -- If AL = 0 then the COM port is closed! ;
- ; ;
- ; Opcode 1+2 -- Same as ASYNC ports but conforms to KISS interface ;
- ; ;
- ; Opcode 3 -- Status ;
- ; No parms ;
- ; Returns AH. AL = 0 ;
- ; x.xxxxx. = not assigned. Zero ;
- ; .x...... = If 0 then packets remain in the transmit queue ;
- ; .......x = If 1 then packets await in the receive queue ;
- ; ;
- ; Opcode 10 -- Send a packet ;
- ; ES = Segment of buffer containing the packet to be sent. ;
- ; Note: The buffer pointed to by ES will be freed when the ;
- ; packet is sent. It should be gotten via Opcode 6. It must ;
- ; be 512 bytes long and conform to the layout of the buffers ;
- ; ;
- ; Opcode 11 -- Receive a packet ;
- ; Returns ES with segment of buffer containing the packet ;
- ; recieved. If zero, no such packet exists. ;
- ; ;
- ; Opcode 12 -- Buffer management ;
- ; If ES is zero then returns a buffer segment in ES. ;
- ; If ES is non-zero then the buffer pointed to is freed. ;
- ; ;
- ; Opcode 13 -- Set TXD -- time from RTS to start of packet. ;
- ; AL = new setting in clock counts ;
- ; ;
- ; Opcode 14 -- Set P -- Controls time from end of DCD to RTS ;
- ; AL = new setting. 1.0 = 255 ;
- ; ;
- ; Opcode 15 -- Set slot time -- Controls time from end of DCD to RTS ;
- ; AL = new setting in clock counts ;
- ; ;
- ; Opcode 16 -- Set CRC wait -- time from start of last character to drop ;
- ; RTS.. Should be 5 character lengths minimum ;
- ; AL = new setting in clock counts ;
- ; ;
- ;==========================================================================;
-
- rcvbuf_8530 EQU 00000001B ; Receive buffer has data in it
- txbuf_8530 EQU 10111111B ; Transmit buffer has data in it (inverted)
-
- CLI ; Interrupts off!
-
- MOV BL,AH ; Use BX so we can jump
- SUB BH,BH ; Use BX so we can jump
- CMP BL,16 ; Legal value?
- JA svc_8530_not_us ; Nope.. Pass on down
- SHL BL,1 ; *2 for words
- JMP DS:svc_8530_br[BX] ; Go where we gotta go
-
- svc_8530_not_us: ;
- JMP rsint_exit_not_us ;
-
- svc_8530_br LABEL WORD ;
-
- DW OFFSET rsint_8530_init ; 0 = Init
- DW OFFSET rsint_8530_kiss_t ; 1 = Send character
- DW OFFSET rsint_8530_kiss_r ; 2 = Rcv character
- DW OFFSET rsint_8530_status ; 3 = Status
- DW OFFSET rsint_8530_query ; 4 = Query
- DW OFFSET rsint_8530_ignore ; 5 = Nothing
- DW OFFSET rsint_8530_ignore ; 6 = Nothing
- DW OFFSET rsint_8530_ignore ; 7 = Nothing
- DW OFFSET rsint_8530_ignore ; 8 = Nothing
- DW OFFSET rsint_8530_ignore ; 9 = Nothing
- DW OFFSET rsint_8530_sendp ; 10 = Send Packet
- DW OFFSET rsint_8530_recvp ; 11 = Receive Packet
- DW OFFSET rsint_8530_buff ; 12 = Get/Free buffer
- DW OFFSET rsint_8530_txd ; 13 = Set TXD
- DW OFFSET rsint_8530_setp ; 14 = Set P
- DW OFFSET rsint_8530_slot ; 15 = Set slot
- DW OFFSET rsint_8530_crcwt ; 16 = Set CRC wait
-
- rsint_8530_ignore:
- MOV AX,0FFFFH ; All ones for error
- JMP rsint_exit ;
-
- ;==========================================================================;
- ; Inquiry ;
- ;==========================================================================;
-
- rsint_8530_query:
-
- MOV AX,0AA55H ; Set footprint
- JMP rsint_exit ; All done
-
- ;--------------------------------------------------------------------------;
- ; Speed tables for 8530 PACCOMM board. Entries are in the same order as ;
- ; original BIOS ;
- ; ;
- ; 1st table = Divisor when DPLL is on (X32 clock) ;
- ; 2nd table = Divisor when DPLL is off (X1 clock) ;
- ; 3nd table = Data rate table -- Type "B" card ;
- ; 4rd table = Modem setting -- 7910 -- Type "A" card ;
- ; 5th table = Modem setting -- 7910 -- Type "B" card ;
- ; 6th table = Modem setting -- TCM3105 -- Type "B" card ;
- ; ;
- ;--------------------------------------------------------------------------;
-
- divx32_8530 LABEL WORD ; 7910 clock data for X32 and 2.4576 xtal
-
- DW 015BH ; 110 bps - X32 clock - 0
- DW 00FEH ; 150 bps - X32 clock - 1
- DW 007EH ; 300 bps - X32 clock - 2
- DW 003EH ; 600 bps - X32 clock - 3
- DW 001EH ; 1200 bps - X32 clock - 4
- DW 000EH ; 2400 bps - X32 clock - 5
- DW 0006H ; 4800 bps - X32 clock - 6
- DW 0002H ; 9600 bps - X32 clock - 7
-
- divx1_8530 LABEL WORD ; 7910 clock data for X1 and 2.4576 Mhz xtal
-
- DW 26A0H ; 110 bps - X1 clock
- DW 1FFCH ; 150 bps - X1 clock
- DW 0FFCH ; 300 bps - X1 clock
- DW 07FEH ; 600 bps - X1 clock
- DW 03FEH ; 1200 bps - X1 clock
- DW 01FEH ; 2400 bps - X1 clock
- DW 00FEH ; 4800 bps - X1 clock
- DW 007EH ; 9600 bps - X1 clock
-
- divdr_8530 LABEL WORD ; Corresponds table value to data rate
- ; times 64 and divided by 10. Used to
- ; calculate divider setting
-
- DW 704 ; 110 bps
- DW 960 ; 150 bps
- DW 1920 ; 300 bps
- DW 3840 ; 600 bps
- DW 7680 ; 1200 bps
- DW 15360 ; 2400 bps
- DW 30720 ; 4800 bps
- DW 61440 ; 9600 bps
-
- modem_8530_a1 LABEL BYTE ; Type "A" card 7910 Modem bits...
- ; Bottom 4 bits are:
- ; MC3, MC2, MC1, MC0
- ; The 7910 is on both channels
-
- DB 01H ; 110 bps - Modem setting -- 103 Answer
- DB 01H ; 150 bps - Modem setting -- 103 Answer
- DB 01H ; 300 bps - Modem setting -- 103 Answer
- DB 02H ; 600 bps - Modem setting -- 202
- DB 02H ; 1200 bps - Modem setting -- 202
- DB 02H ; 2400 bps - Modem setting -- 202 Probably
- DB 02H ; 4800 bps - Modem setting -- 202 won't
- DB 02H ; 9600 bps - Modem setting -- 202 work
-
- modem_8530_b1 LABEL BYTE ; Type "B" card 7910 Modem bits...
- ; Bottom 4 bits are:
- ; MC0, MC2, MC1, MC3
- ; The 7910 is on "A" channel only
-
- DB 08H ; 110 bps - Modem setting -- 103 Answer
- DB 08H ; 150 bps - Modem setting -- 103 Answer
- DB 08H ; 300 bps - Modem setting -- 103 Answer
- DB 02H ; 600 bps - Modem setting -- 202
- DB 02H ; 1200 bps - Modem setting -- 202
- DB 02H ; 2400 bps - Modem setting -- 202 Probably
- DB 02H ; 4800 bps - Modem setting -- 202 won't
- DB 02H ; 9600 bps - Modem setting -- 202 work
-
- ; Note.. The high order bit controls loopback
- ; mode. It is forced on. All this does is
- ; make the tones use the same pair for both
- ; transmit and receive
-
- modem_8530_b2 LABEL BYTE ; Type "B" card TCM3105 Modem Bits
- ; Upper 4 bits are:
- ; special, TRS(thru J3), TXR1, TXR2
- ; The 3105 is on "B" channel only
- ; The special bit is the 7910 loop back
- ; bit and we force it on!
-
- DB 00H ; Only one setting for this sucker!
- ; Bell 202, 1200 bps
-
- word_100 DW 100 ; This constant is here so we can divide later
-
- ;==========================================================================;
- ; Init.. ;
- ; The init character is similar to the one for BIOS ;
- ; xxx..... -- Baud rate. Same meanings as for BIOS ;
- ; ...000.. -- Must be zero! ;
- ; ......x. -- Passthru packets in error if on ;
- ; .......x -- Full duplex if on ;
- ; ;
- ; If AL is all zero then disable the channel ;
- ; ;
- ;==========================================================================;
-
- rsint_8530_init:
-
- ;--------------------------------------------------------------------------;
- ; Special check for off! If it is, do it ;
- ;--------------------------------------------------------------------------;
-
- OR AL,AL ; Turn off?
- JNZ rsint_8530_i_go ; Nope.. Initialize the thing
-
- AND flags,0FFH-flags_in_use ; This block is closed!
-
- MOV DX,baseaddr[SI] ; Get port address
- CALL off_8530 ; Disable this channel
-
- JMP rsint_exit ; Leave
-
- rsint_8530_i_go: ;
-
- MOV flags[SI],flags_in_use ; This block is open!
-
- ;--------------------------------------------------------------------------;
- ; Set options ;
- ;--------------------------------------------------------------------------;
-
- MOV BL,AL ; Get the options bits
- AND BL,00011111B ; Remove baud rate parameter
- MOV BH,options[SI] ; Get current options
- AND BH,11100000B ; Remove the ones we are about to set
- OR BL,BH ; Make new options byte
- MOV options[SI],BL ; And save
-
- ;--------------------------------------------------------------------------;
- ; Initialize the modem ;
- ;--------------------------------------------------------------------------;
-
- MOV DX,baseaddr[SI] ; Get port address
-
- MOV CL,5 ; Get baud rate parameter
- SHR AL,CL ;
- AND AX,07H ;
-
- MOV data_rate[SI],AL ; Save baud rate
- MOV BX,AX ; Put baud rate into work register
-
- MOV AH,modem_8530_a1[BX] ; Get the new modem setting for type "A"
- CMP type_8530[SI],type_8530_a ; Type "A" card?
- JE rsinit_8530_modem_do ; Yep!
-
- ; Must be a type "B" card to get here
-
- MOV AH,modem_8530_b1[BX] ; Get the new 7910 modem setting for "B"
- TEST DX,scc_chan_mask ; Channel "A" or "B"
- JNZ rsinit_8530_modem_do ; Channel "A" -- 7910!
-
- MOV AH,modem_8530_b2 ; Type "B" 3105 modem setting (only one)
-
- rsinit_8530_modem_do: ; AH = new modem setting when we get here
-
- MOV DI,chip_comm[SI] ; Get chip common pointer
- MOV AL,DS:4[DI] ; Get current byte setting
-
- TEST DX,scc_chan_mask ; Channel "A" or "B"
- JNZ rsinit_8530ia ; Channel "A"
-
- AND AL,0F0H ; Remove old channel "B" setting
- OR AL,AH ; Put in the modem setting
- JMP SHORT rsinit_8530_modem_set ; Go init the modem
-
- rsinit_8530ia:
- AND AL,0FH ; Remove old channel "A" setting
- MOV CL,4 ;
- SHL AH,CL ; Shift it to where it belongs
- OR AL,AH ; and form the new modem setting
-
- rsinit_8530_modem_set:
-
- MOV DS:4[DI],AL ; Save the new modem setting
-
- ; Channel A setting is in top half of AL
- ; Channel B setting is in bottom half of AL
- ; This is backwards for the "TYPE B" card
-
- CMP type_8530[SI],type_8530_a ; Type "A" card?
- JE rsinit_8530_modem_set2 ; Yep!
-
- MOV CL,4 ; Rotate the register to flip flop the
- ROR AL,CL ; A and B channels
- OR AL,10000000B ; Turn on M4 bit always. This forces the
- ; the 7910 into loopback mode.
-
- rsinit_8530_modem_set2:
-
- AND DX,scc_card_mask ; Back to address of card
- ADD DX,scc_modem ; Now change to modem address
- OUT DX,AL ; Set the modems
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 9 -- Reset the channel.. ;
- ;--------------------------------------------------------------------------;
-
- MOV DX,baseaddr[SI] ; Get port address
-
- MOV AL,sccreg9 ; Point at WR9
- OUT DX,AL ;
-
- MOV AL,chareset ; Guess Channel A reset
- TEST DX,scc_chan_mask ; Channel "A" or "B"
- JNZ rsinit_8530ra ; Channel "A"
- MOV AL,chbreset ; Wrong guess -- Channel B reset
- rsinit_8530ra: ;
-
- OUT DX,AL ;
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 6 -- SDLC Address field ;
- ; None ;
- ;--------------------------------------------------------------------------;
-
- MOV DX,baseaddr[SI] ; Get port address
-
- MOV AL,sccreg6 ; Point at WR6
- OUT DX,AL ;
- SUB AL,AL ; Zero
- OUT DX,AL ;
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 7 -- SDLC Flag ;
- ; 01111110 ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,sccreg7 ; WR7
- OUT DX,AL ;
- MOV AL,01111110B ;
- OUT DX,AL ;
-
- ;------------------------------------+-------------------------------------;
- ; Setup 8530 -- Register 10 -- Data type ;
- ; CRC preset 1, NRZI, abort on underrun ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,sccreg10 ; WR10
- OUT DX,AL ;
- MOV AL,crc_1or0+nrzimode;
- OUT DX,AL ;
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 4 -- Mode ;
- ; Use 01x, SDLC, no parity ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,sccreg4 ; Point at WR4
- OUT DX,AL ;
- MOV AL,x1_clck+sync_sdl+sync_mod ;
- OUT DX,AL ; Put out
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- If this is channel "A" and channel "B" has not been set ;
- ; then we have to init the clock registers over there to supply XTAL to ;
- ; everyone. This only applies to the PACCOMM type "A" card. ;
- ;--------------------------------------------------------------------------;
-
- MOV DI,chip_comm[SI] ; Get chip common pointer
-
- CMP type_8530[SI],type_8530_a ; Type "A" card (internal Osc)?
- JNE rsinit_8530cb ; Nope!
-
-
- TEST DX,scc_chan_mask ; Channel "A" or "B"
- JZ rsinit_8530cb ; Channel "B"
-
- CMP DS:BYTE PTR 5[DI],0 ; Channel "B" started?
- JNE rsinit_8530cb ; Channel "B"
-
- AND DL,0FFH-scc_chan_mask ; Channel "B" now
- MOV AL,sccreg11 ; Point at WR11
- OUT DX,AL ;
- MOV AL,xtal_osc+rxc_brg+txc_brg+trxc_out+trxc_xtl ;
- OUT DX,AL ; Put out
- OR DL,scc_chan_mask ; Back to channel "A"
-
- rsinit_8530cb:
-
- MOV DS:BYTE PTR 5[DI],1 ; Channel "B" started!
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Do the clock and receiver ;
- ;--------------------------------------------------------------------------;
-
- CALL ron_clk_8530 ; Receiver and clock setup
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 5 ;
- ; DTR on, 8 bits for transmit, transmit CRC enable, tx enable ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,sccreg5 ; Point at WR5
- OUT DX,AL ;
- MOV AL,dtr_pin+tx_8bits+tx_crcen+tx_enabl ;
- OUT DX,AL ; Transmit
-
- ;--------------------------------------------------------------------------;
- ; Setup Interrupts ;
- ;--------------------------------------------------------------------------;
-
- CALL int_8530 ;
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 9 -- Master interrupt control ;
- ; Enable, no vector, status wanted ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,sccreg9 ; Point at WR9
- OUT DX,AL ;
- MOV AL,int_enab+no_vectr+enab_vis ;
- OUT DX,AL ;
-
- ;--------------------------------------------------------------------------;
- ; Init all done ;
- ;--------------------------------------------------------------------------;
-
- JMP rsint_exit ;
-
- ;==========================================================================;
- ; Send a character in KISS mode ;
- ;==========================================================================;
-
- rsint_8530_kiss_t:
-
- MOV BX,buffer_t_in[SI] ; Get buffer counter
-
- ;--------------------------------------------------------------------------;
- ; This code handles the character after an escape ;
- ;--------------------------------------------------------------------------;
-
- TEST kiss_flag[SI],kiss_r_fesc ; Escape was previous?
- JZ rsint_8530_kt_nescp ; Nope....
-
- CMP AL,kiss_tfesc ; Transposed FESC?
- JNE rsint_8530_kt_ntfesc ; Nope....
- MOV AL,kiss_fesc ; Make an FESC
- JMP rsint_8530_kt_data ; and handle like data
-
- rsint_8530_kt_ntfesc:
-
- CMP AL,kiss_tfesc ; Transposed FEND?
- JNE rsint_8530_kt_nescp ; Nope.... Just pass thru
- MOV AL,kiss_fend ; Make an FEND
- JMP rsint_8530_kt_data ; and handle like data
-
- rsint_8530_kt_nescp:
-
- ;--------------------------------------------------------------------------;
- ; Check for FEND ;
- ;--------------------------------------------------------------------------;
-
- CMP AL,kiss_fend ; Is the incoming data FEND?
- JE rsint_8530_kt_isfend ; Yes.....
- JMP rsint_8530_kt_notfend ; Nope....
- rsint_8530_kt_isfend:
-
- ;--------------------------------------------------------------------------;
- ; Incoming character is FEND.. It either starts or ends a packet. ;
- ;--------------------------------------------------------------------------;
-
- OR BX,BX ; Is buffer counter zero?
- JNZ rsint_8530_kt_notstart ; No... Must be an end of frame
- JMP rsint_8530_kt_start ; Yes.. Must be a start of frame
- rsint_8530_kt_notstart:
-
- ;--------------------------------------------------------------------------;
- ; Incoming character is FEND.. It ends a packet... ;
- ;--------------------------------------------------------------------------;
-
- CMP kiss_type[SI],kiss_data ; Is this a data packet
- JNE rsint_8530_kt_cmd ; Nope... Its a command
-
- MOV ES,buffer_t_seg[SI] ; Get buffer's address
- MOV ES:buffer_dl,BX ; Set length
-
- MOV buffer_t_seg[SI],0 ; Clear buffer pointer
- MOV buffer_t_in[SI],0 ; Clear buffer counter
-
- JMP rsint_8530_sendp ; Send the packet
-
- ;--------------------------------------------------------------------------;
- ; This code handles a stream from the host that has a KISS command and ;
- ; not data in it. ;
- ;--------------------------------------------------------------------------;
-
- rsint_8530_kt_cmd:
-
- MOV buffer_t_in[SI],0 ; Clear buffer counter
- AND kiss_flag[SI],0FFH-kiss_r_fesc ; Turn off escape flag
-
- TEST kiss_flag[SI],kiss_t_valid ; Type valid?
- JZ rsint_8530_kt_i ; No.... Ignore packet
- AND kiss_flag[SI],0FFH-kiss_t_valid ; Turn off type flag
-
- MOV BL,kiss_type[SI] ; Get type
-
- CMP BL,kiss_fesc ; Is this an escape command
- JE rsint_8530_kt_i ; Yes... Ignore packet
-
- MOV ES,buffer_t_seg[SI] ; Get the buffer address
- MOV AL,ES:0 ; Get the data byte
- SUB AH,AH ; Clear type of the word
-
- SUB BH,BH ; Make the type a word
- DEC BL ; Base of index = 1 so make 0
- SHL BL,1 ; And make it address a word
- JMP DS:rsint_8530_kt_j[BX] ; Go where we gotta go
-
- rsint_8530_kt_j LABEL WORD ;
-
- DW OFFSET rsint_8530_kt_txd ; 1 = TXD
- DW OFFSET rsint_8530_kt_p ; 2 = P
- DW OFFSET rsint_8530_kt_slot ; 3 = Slot time
- DW OFFSET rsint_8530_kt_crc ; 4 = TxTail (CRC time)
- DW OFFSET rsint_8530_kt_fds ; 5 = Full duplex switch
- DW OFFSET rsint_8530_kt_i ; 6 = Set link speed
-
- rsint_8530_kt_i: ; Come here to ignore the command
- JMP rsint_8530_status ;
-
- five DB 5 ; Needed for divide
-
- rsint_8530_kt_txd: ; Set TXD - value in 10ms increments
- ADD AL,3 ; Change value to 50ms increments. This
- DIV five ; is close to our 54ms clock pulses
- CBW ; Need to store a word
- OR AX,AX ; Don't store zero!
- JNZ rsint_8530_kt_txd_ok; If the user tries this,
- MOV AX,1 ; use 1 instead
- rsint_8530_kt_txd_ok:
- MOV value_txd[SI],AX ; Set TXD
- JMP rsint_8530_status ; Exit
-
- rsint_8530_kt_p: ; Set P
- MOV value_p[SI],AL ;
- JMP rsint_8530_status ; Exit
-
- rsint_8530_kt_slot: ; Set Slot time - value in 10ms increments
- ADD AL,3 ; Change value to 50ms increments. This
- DIV five ; is close to our 54ms clock pulses
- OR AL,AL ; Don't store zero!
- JNZ rsint_8530_kt_slot_ok; If the user tries this,
- MOV AL,1 ; use 1 instead
- rsint_8530_kt_slot_ok:
- MOV value_slot[SI],AL ; Set slot
- JMP rsint_8530_status ; Exit
-
- rsint_8530_kt_crc: ; Set CRC - value in 10ms increments
- ADD AL,3 ; Change value to 50ms increments. This
- DIV five ; is close to our 54ms clock pulses
- CBW ; Need to store a word
- OR AX,AX ; Don't store zero!
- JNZ rsint_8530_kt_crc_ok; If the user tries this,
- MOV AX,1 ; use 1 instead
- rsint_8530_kt_crc_ok:
- MOV value_crc[SI],AX ; Set CRC
- JMP rsint_8530_status ; Exit
-
- rsint_8530_kt_fds: ; Set full duplex switch
- MOV AH,options[SI] ; Get options switch
- AND AH,0FFH-opt_fd ; Remove old setting
- OR AL,AL ; Turn switch on or off?
- JZ rsint_8530_kt_fds_0 ; Switch is off
- OR AH,opt_fd ; Switch is on
- rsint_8530_kt_fds_0:
- MOV options[SI],AH ; Put the switch back
- JMP rsint_8530_status ; Exit
-
- ;--------------------------------------------------------------------------;
- ; Incoming character is FEND.. It may start a packet ;
- ;--------------------------------------------------------------------------;
-
- rsint_8530_kt_start: ;
-
- AND kiss_flag[SI],0FFH-kiss_t_valid-kiss_r_fesc ; Turn off type
- ; and escape flags
- MOV kiss_type[SI],kiss_escape ; Set type to escape
-
- JMP rsint_8530_status ; Send staus back
-
- ;--------------------------------------------------------------------------;
- ; Incoming character is not FEND.. Handle first character in packet if it ;
- ; is one ;
- ;--------------------------------------------------------------------------;
-
- rsint_8530_kt_notfend:
-
- OR BX,BX ; Is buffer counter zero?
- JNZ rsint_8530_kt_data ; No... Can't be first byte. Its data
- TEST kiss_flag[SI],kiss_t_valid ; Type loaded?
- JNZ rsint_8530_kt_data ; Yes.. This is the first data byte
-
- CMP AL,kiss_escape ; Is this KISS escape
- JE rsint_8530_kt_okt ; Yep... Type ok
-
- CMP AL,kiss_last_type ; Is this within the valid modes?
- JBE rsint_8530_kt_okt ; Yep... Mode ok
-
- MOV AL,kiss_escape ; Invalid type.. Use escape
-
- rsint_8530_kt_okt:
-
- MOV kiss_type[SI],AL ; Set the incoming data type
- OR kiss_flag[SI],kiss_t_valid ; Type valid
-
- JMP rsint_8530_status ; Go send status
-
- ;--------------------------------------------------------------------------;
- ; This code handles data characters ;
- ;--------------------------------------------------------------------------;
-
- rsint_8530_kt_data:
-
- CMP BX,buffer_siz2 ; Will we overflow the buffer?
- JA rsint_8530_kt_done ; Yes.... Ignore the character
-
- MOV DX,buffer_t_seg[SI] ; Get the buffer address
- MOV ES,DX ;
- OR DX,DX ; Is there one?
- JNZ rsint_8530_kt_sdata ; Yes... Use it
-
- MOV DL,AL ; Save incoming data
- CALL get_a_buffer ; Get the new buffer for the chain
- OR AX,AX ; Did we find one?
- JZ rsint_8530_kt_done ; NO.. Ignore the character
-
- MOV buffer_t_seg[SI],AX ; Set the buffer address
- MOV ES,AX ; Set the registers straight
- MOV AL,DL ;
-
- rsint_8530_kt_sdata:
-
- MOV ES:0[BX],AL ; Save the data byte
-
- INC BX ; Bump counter and
- MOV buffer_t_in[SI],BX ; save
-
- rsint_8530_kt_done:
-
- JMP rsint_8530_status ; Leave
-
- ;==========================================================================;
- ; Receive a character in KISS mode ;
- ;==========================================================================;
-
- rsint_8530_kiss_r:
-
- ;--------------------------------------------------------------------------;
- ; See if we have something in progress. If we do then that is goodness. ;
- ; If not we have to check the whole queue. This simply shortcuts the ;
- ; need to search the whole queue every time. ;
- ;--------------------------------------------------------------------------;
-
- MOV ES,buffer_r_seg[SI] ; Get the shortcut buffer address
- MOV AX,ES ; Now put it somewhere handy
- OR AX,AX ; Anything there?
- JNZ rsint_8530_kr_do ; Yep... Take the shortcut
-
- ;--------------------------------------------------------------------------;
- ; See if we have anything. We loop here if nothing doing. Enable ;
- ; interrupts to permit something to work. ;
- ;--------------------------------------------------------------------------;
-
- STI ; Interrupt enable
-
- rsint_8530_kr_loop1:
-
- MOV ES,buffer_r_a[SI] ; Get the current buffer address
- MOV AX,ES:buffer_next ; Get head of queue
- OR AX,AX ; Anything in queue?
- JZ rsint_8530_kr_loop1 ; Yep.. Go process it
-
- ;--------------------------------------------------------------------------;
- ; Ok! Something is here.. We now have to scurry down the queue to find ;
- ; the last entry because it is the oldest! Disable interrupts to prevent ;
- ; someone from messing with it ;
- ;--------------------------------------------------------------------------;
-
- CLI ; Interrupt disable
-
- MOV ES,buffer_r_a[SI] ; Get the current buffer address
- MOV BX,ES ; Save this!
- MOV ES,ES:buffer_next ; Get head of queue
-
- rsint_8530_kr_loop2:
-
- MOV AX,ES:buffer_next ; Get --> to next in queue
- OR AX,AX ; Anything there?
- JZ rsint_8530_kr_found ; Nope.. Found end of queue
- MOV BX,ES ; Save last
- MOV ES,AX ; Point to next
- JMP rsint_8530_kr_loop2 ; Loop back for more
-
- rsint_8530_kr_found:
-
- STI ; Reenable interrupts
-
- MOV buffer_r_seg[SI],ES ; Set it up for shortcut next time.
- JMP SHORT rsint_8530_kr_fs ; Go send beginning FEND
-
- ;--------------------------------------------------------------------------;
- ; ES now points to a buffer with our data in it. Get current mode ;
- ; and go to it. ;
- ;--------------------------------------------------------------------------;
-
- rsint_8530_kr_do:
-
- MOV BL,kiss_flag[SI] ; Get the KISS-R mode
- AND BL,kiss_r_mode ;
- SUB BH,BH ;
- JMP DS:rsint_8530_krjmp[BX] ; Go where we gotta go
-
- rsint_8530_krjmp LABEL WORD ; Branch table
- DW OFFSET rsint_8530_kr_fs ; 0 = Start packet FEND
- DW OFFSET rsint_8530_kr_type ; 1 = Type
- DW OFFSET rsint_8530_kr_data ; 2 = Data
- DW OFFSET rsint_8530_kr_fe ; 3 = End packet FEND
-
- rsint_8530_kr_modes: ; Subroutine to set KISS-R mode
- MOV AL,kiss_flag[SI] ; Get the whole flag byte
- AND AL,0FFH-kiss_r_mode ; Remove the current mode setting
- OR AL,BL ; Put new one in
- MOV kiss_flag[SI],AL ; Put byte pack
- RET ; Return to caller
-
- ;--------------------------------------------------------------------------;
- ; Start a packet by sending FEND ;
- ;--------------------------------------------------------------------------;
-
- rsint_8530_kr_fs: ; Start packet FEND
-
- MOV buffer_r_out[SI],0 ; Clear output pointer
- MOV BL,kiss_r_mtype ; Set mode to data
- CALL rsint_8530_kr_modes ;
- MOV AX,kiss_fend ; Output FEND. We zero AH this way too..
- JMP rsint_8530_status_ah ; Go load AH status data.
-
- ;--------------------------------------------------------------------------;
- ; Send the packet type ;
- ;--------------------------------------------------------------------------;
-
- rsint_8530_kr_type: ; Start packet FEND
-
- MOV AX,kiss_data ; Signal data frame -- zero AX this way
- MOV BL,kiss_r_mdata ; Set mode to data
- CALL rsint_8530_kr_modes ;
- JMP rsint_8530_status_ah ; Go load AH status data.
-
- ;--------------------------------------------------------------------------;
- ; Send packet data. Don't forget check for special characters ;
- ;--------------------------------------------------------------------------;
-
- rsint_8530_kr_data: ; Send packet data
-
- MOV AX,kiss_fesc ; Clear AH for call to status
- ; Set AL to escape if needed
-
- MOV BX,buffer_r_out[SI] ; Get output pointer
- MOV DL,ES:[BX] ; Get a data byte
-
- CMP DL,kiss_fend ; Data is FEND?
- JE rsint_8530_kr_dfend ; YES... Escape needed.
-
- CMP DL,kiss_fesc ; Data is FESC?
- JE rsint_8530_kr_dfesc ; YES... Escape needed.
-
- MOV AL,DL ; Regular data, let it go
- INC BX ; Increment pointer
- CMP BX,ES:buffer_dl ; Are we at the end of the data in buffer
- JAE rsint_8530_kr_end ; Yes....
-
- MOV buffer_r_out[SI],BX ; Save new output pointer
- JMP rsint_8530_status_ah ; Go load AH status data.
-
- ; End of buffer detected.
-
- rsint_8530_kr_end: ; End of buffer but last data char in AL
-
- MOV BL,kiss_r_mfe ; Set mode to ending FEND
- CALL rsint_8530_kr_modes ;
- JMP rsint_8530_status_ah ; Go load AH status data.
-
- ; FEND found in data
-
- rsint_8530_kr_dfend: ; FEND in data stream
-
- MOV BYTE PTR ES:[BX],kiss_tfend ; Make the data a transposed FEND
- ; AL already has an FESC in it. Don't
- ; bump the pointer so we will send TFEND
- JMP rsint_8530_status_ah ; Go load AH status data.
-
- ; FESC found in data
-
- rsint_8530_kr_dfesc: ; FESC in data stream
-
- MOV BYTE PTR ES:[BX],kiss_tfesc ; Make the data a transposed FESC
- ; AL already has an FESC in it. Don't
- ; bump the pointer so we will send TFESC
- JMP rsint_8530_status_ah ; Go load AH status data.
-
- ;--------------------------------------------------------------------------;
- ; Send ending FEND and free everything up ;
- ;--------------------------------------------------------------------------;
-
- rsint_8530_kr_fe:
-
- MOV buffer_r_out[SI],0 ; Clear output pointer
- MOV buffer_r_seg[SI],0 ; Clear shortcut buffer address
-
- CLI ; Disable interrupts
-
- MOV ES,buffer_r_a[SI] ; Get the current buffer address
- MOV BX,ES ;
-
- rsint_8530_kr_feloop1:
-
- MOV AX,ES:buffer_next ; Get --> to next in queue
- OR AX,AX ; Anything there?
- JZ rsint_8530_kr_fefnd ; Nope.. Found end of queue
- MOV BX,ES ; Save last
- MOV ES,AX ; Point to next
- JMP rsint_8530_kr_feloop1 ; Loop back for more
-
- rsint_8530_kr_fefnd:
-
- ; ES = address of buffer we are finishing
- ; BX = buffer that points to one in ES
-
- MOV AX,ES ; Free this buffer
- CALL free_a_buffer ; Free a buffer instead
-
- MOV ES,BX ; Go back one buffer
- MOV ES:buffer_next,0 ; and zero his pointer
-
- STI ; Reenable interrupts
-
- MOV AX,kiss_fend ; Send FEND
- JMP rsint_8530_status_ah ; Go load AH status data.
-
- ;==========================================================================;
- ; Send a packet -- ES points to buffer to be sent. ;
- ;==========================================================================;
-
- rsint_8530_sendp:
-
- MOV ES:buffer_next,0 ; Put a zero in next buffer address
-
- ;--------------------------------------------------------------------------;
- ; See if queue is empty. If so this packet is the whole queue. We also ;
- ; need to attempt to turn on the transmitter ;
- ;--------------------------------------------------------------------------;
-
- MOV AX,buffer_t_a[SI] ; Get the transmit buffer address
- OR AX,AX ; Is there one?
- JNZ rsint_8530_sendp_q ; Yes. Must add this packet to the q
-
- ; This buffer is the whole queue. Put at the head
-
- MOV buffer_t_a[SI],ES ; Put this buffer on head of queue
- MOV ES:buffer_next,AX ; Put a zero in next buffer address
-
- ; Now try to turn on the transmitter
-
- TEST flags[SI],flags_xmt_on ; Transmitter on?
- JNZ rsint_8530_sendp_x ; Yes.. Don't do anything
- TEST options[SI],opt_fd ; Full duplex?
- JNZ rsint_8530_sendp_t ; Yes.. Go turn on transmitter
- TEST flags[SI],flags_dcd_on ; DCD on?
- JNZ rsint_8530_sendp_x ; Yes.. Don't do anything
-
- MOV AX,timer_dcd[SI] ; Get timer
- CMP AL,value_slot[SI] ; Slot expired?
- JB rsint_8530_sendp_x ; No... Don't do anything
-
- CALL random ; Get a random number
- CMP AL,value_p[SI] ; Check against "P" (the probability)
- JA rsint_8530_sendp_x ; Too big... Don't do anything
-
- ; Turn on transmitter
-
- rsint_8530_sendp_t: ;
-
- MOV DX,baseaddr[SI] ; Get port address
- CALL ton_clk_8530 ; Call the transmitter routine
-
- ; Do nothing
-
- rsint_8530_sendp_x: ;
-
- JMP rsint_exit ; Leave
-
- ;--------------------------------------------------------------------------;
- ; Add this packet to the transmit queue. ;
- ;--------------------------------------------------------------------------;
-
- rsint_8530_sendp_q: ;
-
- MOV BX,ES ; Save address of buffer to add to queue
-
- ; Loop around to find end of chain
-
- rsint_8530_sendp_loop:
-
- MOV ES,AX ; Address of buffer to test
- MOV AX,ES:buffer_next ; Get next one in chain
- OR AX,AX ; Anything left?
- JNZ rsint_8530_sendp_loop ; Yep.. Try again
-
- MOV ES:buffer_next,BX ; Add to chain
-
- JMP rsint_exit ; Leave
-
- ;==========================================================================;
- ; Receive a packet ;
- ;==========================================================================;
-
- rsint_8530_recvp:
-
- ;--------------------------------------------------------------------------;
- ; See if we have anything. We loop here if nothing doing. Enable ;
- ; interrupts to permit something to work. ;
- ;--------------------------------------------------------------------------;
-
- STI ; Interrupt enable
-
- rsint_8530_recvp_loop1:
-
- MOV ES,buffer_r_a[SI] ; Get the current buffer address
- MOV AX,ES:buffer_next ; Get head of queue
- OR AX,AX ; Anything in queue?
- JZ rsint_8530_recvp_loop1 ; Yep.. Go process it
-
- ;--------------------------------------------------------------------------;
- ; Ok! Something is here.. We now have to scurry down the queue to find ;
- ; the last entry because it is the oldest! Disable interrupts to prevent ;
- ; someone from messing with it ;
- ;--------------------------------------------------------------------------;
-
- CLI ; Interrupt disable
-
- MOV ES,buffer_r_a[SI] ; Get the current buffer address
- MOV BX,ES ; Save this!
- MOV ES,ES:buffer_next ; Get head of queue
-
- rsint_8530_recvp_loop2:
-
- MOV AX,ES:buffer_next ; Get --> to next in queue
- OR AX,AX ; Anything there?
- JZ rsint_8530_recvp_done ; Nope.. Found end of queue
- MOV BX,ES ; Save last
- MOV ES,AX ; Point to next
- JMP rsint_8530_recvp_loop2 ; Loop back for more
-
- rsint_8530_recvp_done:
-
- ;--------------------------------------------------------------------------;
- ; Found the last item in the chain. Remove it from the queue and give ;
- ; it back to the user! ;
- ;--------------------------------------------------------------------------;
-
- MOV AX,ES ; This is the guy with the oldest data
- MOV ES,BX ; Restore the old pointer. This is the
- MOV ES:buffer_next,0 ; guy who contains the pointer we must zero!
-
- ;--------------------------------------------------------------------------;
- ; All done ;
- ;--------------------------------------------------------------------------;
-
- JMP rsint_exit ;
-
- ;==========================================================================;
- ; Status.. ;
- ;==========================================================================;
-
- rsint_8530_status:
-
- SUB AX,AX ; No status so far!
-
- rsint_8530_status_ah: ; This entry point used to set AH only.
- ; This is for when data is in AL. AH
- ; must be zero to use this entry point.
-
- MOV ES,buffer_r_a[SI] ; Get the current rcvr buffer address
- MOV BX,ES:buffer_next ; Get head of queue
-
- OR BX,BX ; Any packets waiting in receive buffer?
- JZ rsint_8530_statnor ; Nope...
- OR AH,rcvbuf_8530 ; Yep.... turn on low order bit
- rsint_8530_statnor: ;
-
- MOV BX,buffer_t_a[SI] ; Get the current xmit buffer address
-
- AND AH,txbuf_8530 ; Turn off the empty transmit bit
- OR BX,BX ; Any packets in transmit queue?
- JNZ rsint_8530_statnot ; Yep....
- OR AH,0FFH-txbuf_8530 ; Turn on the empty transmit bit
- rsint_8530_statnot: ;
-
- JMP rsint_exit ;
-
- ;==========================================================================;
- ; Buffer control - Get/Free ;
- ;==========================================================================;
-
- rsint_8530_buff:
-
- MOV AX,ES ; Put it in parameter register
- OR AX,AX ; Did user supply an address
- JZ rsint_8530_get ; No.. Get him a buffer
-
- CALL free_a_buffer ; Free a buffer instead
- JMP rsint_exit ;
-
- rsint_8530_get:
- CALL get_a_buffer ;
- JMP rsint_exit ;
-
- ;==========================================================================;
- ; Set Timing values.. TXD, P, SLOT, CRC wait ;
- ;==========================================================================;
-
- rsint_8530_txd:
- SUB AH,AH ; Clear high order byte
- MOV value_txd[SI],AX ; Set value
- JMP rsint_exit ;
-
- rsint_8530_setp:
- OR AL,AL ; Can't set zero!
- JZ rsint_8530_setp_0 ;
- MOV value_p[SI],AL ; Set value
- rsint_8530_setp_0: ;
- JMP rsint_exit ;
-
- rsint_8530_slot:
- MOV value_slot[SI],AL ; Set value
- JMP rsint_exit ;
-
- rsint_8530_crcwt:
- SUB AH,AH ; Clear high order byte
- MOV value_crc[SI],AX ; Set value
- JMP rsint_exit ;
-
- ;==========================================================================;
- ;==========================================================================;
- ;==========================================================================;
- ; 8530 Service subroutines. Used by both the Service and the interrupt ;
- ; handlers ;
- ;==========================================================================;
-
- ;==========================================================================;
- ; 8530 Interrupt control ;
- ;==========================================================================;
-
- int_8530:
-
- ;--------------------------------------------------------------------------;
- ; Basic setup for R15 is DCD. ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,sccreg15 ; Point at WR15
- OUT DX,AL ;
-
- MOV AL,dcd_ie ;
-
- ;--------------------------------------------------------------------------;
- ; If we have are receiving, want break/abort! ;
- ;--------------------------------------------------------------------------;
-
- TEST flags[SI],flags_dcd_on ; Receiver on?
- JZ int_8530_no_rx1 ; Nope..
-
- OR AL,rxie_brk ; Want abort/break!
-
- int_8530_no_rx1:
-
- ;--------------------------------------------------------------------------;
- ; If we have are transmitting data then we want TX underruns ;
- ;--------------------------------------------------------------------------;
-
- TEST flags[SI],flags_xmt_on ; Transmitter on?
- JZ int_8530_no_tx1 ; Nope..
- CMP period_xmtr[SI],period_x_tx ; Event = sending data
- JNE int_8530_no_tx1 ; Nope..
-
- OR AL,txie_eom ; Add eom interrupt
-
- int_8530_no_tx1:
-
- ;--------------------------------------------------------------------------;
- ; Now set R15 ;
- ;--------------------------------------------------------------------------;
-
- OUT DX,AL ;
-
- ;--------------------------------------------------------------------------;
- ; Basic setup for R1 is external ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,sccreg1 ; Point at WR1
- OUT DX,AL ;
-
- MOV AL,exi_enab ;
-
- ;--------------------------------------------------------------------------;
- ; If we are transmitting data then we want TX ;
- ;--------------------------------------------------------------------------;
-
- TEST flags[SI],flags_xmt_on ; Transmitter on?
- JZ int_8530_no_tx2 ; Nope..
- CMP period_xmtr[SI],period_x_tx ; Event = sending data
- JNE int_8530_no_tx2 ; Nope..
-
- OR AL,txi_enab ; Add Tx Interrupt Master Enable
-
- int_8530_no_tx2:
-
- ;--------------------------------------------------------------------------;
- ; If we are receiving data then we want RX ;
- ;--------------------------------------------------------------------------;
-
- TEST flags[SI],flags_dcd_on ; Receiver on?
- JZ int_8530_no_rx2 ; Nope..
-
- OR AL,rxi_all ; Add Rx Interrupt Master Enable
-
- int_8530_no_rx2:
-
- ;--------------------------------------------------------------------------;
- ; Now set R1 ;
- ;--------------------------------------------------------------------------;
-
- OUT DX,AL ;
-
- ;--------------------------------------------------------------------------;
- ; Done.. ;
- ;--------------------------------------------------------------------------;
-
- RET ;
-
- ;==========================================================================;
- ; 8530 Ready receiver and clock -- Use only on initialization and on ;
- ; half duplex links. Will destroy timing... ;
- ; ;
- ; Type "B" card is assumed full-duplex as far as clocking. ;
- ; ;
- ; Seconadry entry point: ;
- ; ;
- ; 8530 Ready receiver -- Does not destroy timing ;
- ;==========================================================================;
-
- ron_clk_8530:
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 11 -- Oscillator ;
- ; ;
- ; Type "A" ;
- ; For channel "B": ;
- ; Use Crystal, Clock both rx and tx from DPLL, output xtal on TRXC ;
- ; For channel "A": ;
- ; Use Clock both rx and tx from DPLL ;
- ; ;
- ; Type "B" ;
- ; Rx clock = DPLL, tx clock is RTXC, output BRG on TRXC ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,sccreg11 ; Point at WR11
- OUT DX,AL ;
-
- ; Guess at type B
-
- MOV AL,rxc_dpll+txc_rtxc+trxc_out+trxc_brg ; Type "B" card setting
-
- CMP type_8530[SI],type_8530_a ; Type "A" card (internal Osc)?
- JNE ron_clk_8530bb ; Nope.. Guessed right
-
- ; Type "A" card setting
-
- TEST DX,scc_chan_mask ; Channel "A" or "B"
- JZ ron_clk_8530b1 ; "B"!
- MOV AL,rxc_dpll+txc_dpll ; Setting for "A"
- JMP SHORT ron_clk_8530bb ;
- ron_clk_8530b1:
- MOV AL,xtal_osc+rxc_dpll+txc_dpll+trxc_out+trxc_xtl ;
-
- ; Output the clock setting
-
- ron_clk_8530bb:
-
- OUT DX,AL ; Put out
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 12 and 13 ;
- ; 12 = Lower byte of divisor ;
- ; 13 = Upper byte of divisor ;
- ; ;
- ; For type "A" card with internal oscillator, use tables ;
- ; ;
- ; For type "B" card with external oscillator, use the equation. ;
- ; ;
- ; 32*data_rate = 1 / (brg+2) * clock period ;
- ; ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,sccreg12 ; Point at WR12
- OUT DX,AL ;
- MOV BL,data_rate[SI] ; Get the data rate
- SUB BH,BH ; Zero high order byte
- SHL BL,1 ; *2 for a word lookup
-
- CMP type_8530[SI],type_8530_a ; Type "A" card (internal Osc)?
- JNE ron_clk_8530_bdiv ; Nope.. Guessed right
-
- ron_clk_8530_adiv: ; Clock setting for 8530 Type "A" card
-
- MOV AX,divx32_8530[BX] ; Get the whole divisor
- JMP SHORT ron_clk_8530_dive ; Go set the rate
-
- ron_clk_8530_bdiv: ; Clock setting for 8530 Type "B" card
-
- PUSH DX ; We are gonna lose him on the MUL/DIV
-
- MOV AX,clock_8530[SI] ; Get the clock frequency in Khz
- MUL word_100 ; Multiply by hundred
- DIV divdr_8530[BX] ; Divide by datarate table (which is
- DEC AX ; already divided by 10. The result is
- DEC AX ; the baud rate generator setting in AX
- ; but we still must subtract 2
- POP DX ; Ooopss lost DX is shuffle so get it back
-
- ron_clk_8530_dive: ; Divisor info in AX so set it
-
- OUT DX,AL ; Put out lower byte
-
- MOV AL,sccreg13 ; Point at WR13
- OUT DX,AL ;
- MOV AL,AH ; Get the upper divisor
- OUT DX,AL ; Put out lower byte
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 14 -- DPLL ;
- ; This register has both commands and bit functions ;
- ; 1) NRZI mode ;
- ; 2) DPLL source = BRG ;
- ; 3) Start the BRG ;
- ; ;
- ; If type "B" card, keep selecting BRG in from PCC ;
- ; ;
- ; The rest of WR14 setup happens after the Secondary Entry Point! ;
- ; ;
- ;--------------------------------------------------------------------------;
-
- SUB AH,AH ; Assume type "A" card
-
- CMP type_8530[SI],type_8530_a ; Type "A" card (internal Osc)?
- JE ron_clk_8530_brgrtxc1 ; Yep..
-
- MOV AH,brg_clck ; Set BRG clock in = PCC
-
- ron_clk_8530_brgrtxc1: ; Come here when BRG source is RTXC
-
- MOV AL,sccreg14 ; Point at WR14
- OUT DX,AL ;
- MOV AL,mod_nrzi ; Command -> NRZI
- OR AL,AH ; BRG source bit as determined above
- OUT DX,AL ;
-
- MOV AL,sccreg14 ; Point at WR14
- OUT DX,AL ;
- MOV AL,dpll_brg ; Command -> DPLL source = BRG
- OR AL,AH ; BRG source bit as determined above
- OUT DX,AL ;
-
- MOV AL,sccreg14 ; Point at WR14
- OUT DX,AL ;
- MOV AL,enab_brg ; Start BRG
- OR AL,AH ; BRG source bit as determined above
- OUT DX,AL ;
-
- ;--------------------------------------------------------------------------;
- ; Secondary entry point is here. This is used to start receiving when ;
- ; DCD appears for example! It assumes the clocks are already set. ;
- ;--------------------------------------------------------------------------;
-
- ron_8530:
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 14 -- DPLL ;
- ; This register has both commands and bit functions ;
- ; 1) Put DPLL in search mode. Start the BRG ;
- ;--------------------------------------------------------------------------;
-
- SUB AH,AH ; Assume type "A" card
-
- CMP type_8530[SI],type_8530_a ; Type "A" card (internal Osc)?
- JE ron_clk_8530_brgrtxc2 ; Yep..
-
- MOV AH,brg_clck ; Set BRG clock in = PCC
-
- ron_clk_8530_brgrtxc2: ; Come here when BRG source is RTXC
-
- MOV AL,sccreg14 ; Point at WR14
- OUT DX,AL ;
- MOV AL,dpllsrch+enab_brg ; Command -> DPLL search + start BRG
- OR AL,AH ; BRG source bit as determined above
- OUT DX,AL ;
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 0 and 3 ;
- ; Use the write to WR0 to reset the receive CRC also ;
- ; ;
- ; 8 bits for receive, rx CRC enable. If DCD active then ;
- ; add hunting and rx enable. ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,rst_rcrc ; Reset RX CRC
- OUT DX,AL ;
-
- MOV AL,sccreg3 ; Point at WR3
- OUT DX,AL ;
-
- MOV AL,rx_8bits+rx_crcon ;
- TEST flags[SI],flags_dcd_on ; DCD on?
- JZ ron_8530_nodcd1 ; Nope
- OR AL,hunt_on+rx_enabl ; Yep.. Enable Rx and hunt
- ron_8530_nodcd1: ;
-
- OUT DX,AL ;
-
- ;--------------------------------------------------------------------------;
- ; Setup Interrupt control and go ;
- ;--------------------------------------------------------------------------;
-
- CALL int_8530 ;
-
- RET ; Done
-
- ;==========================================================================;
- ; 8530 Off -- Disable this port on the 8530. ;
- ;==========================================================================;
-
- off_8530:
-
- MOV AL,sccreg1 ; Point at WR1
- OUT DX,AL ;
- SUB AL,AL ;
- OUT DX,AL ; Put out
-
- MOV AL,sccreg15 ; Now to WR15
- OUT DX,AL ;
- SUB AL,AL ; Disable all interrupts!
- OUT DX,AL ;
-
- RET ;
-
- ;==========================================================================;
- ; 8530 Ready transmitter and clock. ;
- ; Type "A" card: ;
- ; For half duplex lines, switch crystal and slow down ;
- ; Full duplex uses DPLL timing so don't mess with clocks ;
- ; Type "B" card: ;
- ; The output of the BRG is routed thru an external divide-by-32 ;
- ; circuit and then used as the transmitter clock. No changes ;
- ; are needed when going from receive to transmit and vice versa. ;
- ;==========================================================================;
-
- ton_clk_8530:
-
- CMP type_8530[SI],type_8530_a ; Type "A" card (internal Osc)?
- JNZ ton_clk_8530_fd ; No... Dont mess with clocks
-
- TEST options[SI],opt_fd ; Full duplex?
- JNZ ton_clk_8530_fd ; Yes.. Dont mess with clocks
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 11 -- Oscillator ;
- ; Use Crystal, Clock both rx and tx from BRG, output xtal on TRXC ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,sccreg11 ; Point at WR11
- OUT DX,AL ;
- TEST DX,scc_chan_mask ; Channel "A" or "B"
- JZ ton_clk_8530b1 ; "B"!
- MOV AL,rxc_brg+txc_brg ; Setting for "A"
- JMP SHORT ton_clk_8530bb ;
- ton_clk_8530b1:
- MOV AL,xtal_osc+rxc_brg+txc_brg+trxc_out+trxc_xtl ;
- ton_clk_8530bb:
- OUT DX,AL ; Put out
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 12 and 13 ;
- ; 12 = Lower byte of divisor ;
- ; 13 = Upper byte of divisor ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,sccreg12 ; Point at WR12
- OUT DX,AL ;
- MOV BL,data_rate[SI] ; Get the data rate
- SUB BH,BH ; Zero high order byte
- SHL BL,1 ; *2 for a word lookup
- MOV AX,divx1_8530[BX] ; Get the whole divisor
- OUT DX,AL ; Put out lower byte
-
- MOV AL,sccreg13 ; Point at WR13
- OUT DX,AL ;
- MOV AL,AH ; Get the upper divisor
- OUT DX,AL ; Put out lower byte
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 14 -- DPLL ;
- ; This register has both commands and bit functions ;
- ; Start brg ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,sccreg14 ; Point at WR14
- OUT DX,AL ;
- MOV AL,enab_brg ; Start BRG
- OUT DX,AL ; Note: Didn't woory about BRG source
- ; Since we don't got thru this code for
- ; A type "B" card
-
- ;--------------------------------------------------------------------------;
- ; Next code is common for both Full and Half Duplex ;
- ;--------------------------------------------------------------------------;
-
- ton_clk_8530_fd:
-
- ;--------------------------------------------------------------------------;
- ; Setup 8530 -- Register 5 -- Transmitter control ;
- ; DTR, 8bits, TX enable, RTS, CRC ;
- ;--------------------------------------------------------------------------;
-
- MOV AL,sccreg5 ; Point at WR5
- OUT DX,AL ;
-
- MOV AL,dtr_pin+tx_8bits+tx_enabl+rts_pin+tx_crcen ;
- OUT DX,AL ;
-
- ;--------------------------------------------------------------------------;
- ; Set flags and stuff ;
- ;--------------------------------------------------------------------------;
-
- OR flags[SI],flags_xmt_on ; Transmitter on!
-
- MOV period_xmtr[SI],period_x_txd ; Event = TXD delay
-
- MOV timer_xmtr[SI],0 ; Set transmitter timer to zero
-
- ;--------------------------------------------------------------------------;
- ; Setup Interrupt control and go ;
- ;--------------------------------------------------------------------------;
-
- CALL int_8530 ;
-
- RET ;